//
//  HMStatusDAL.swift
//  iOSWeibo11
//
//  Created by Apple on 16/8/3.
//  Copyright © 2016年 Apple. All rights reserved.
//

import UIKit

/// 负责微博模型的数据加载,    1.从数据库加载    2.从网络加载
class HMStatusDAL: NSObject {

    static let sharedStatusDAL: HMStatusDAL = HMStatusDAL()
    
    // 删除过期时间的微博. 7 天以前的就称为过期的微博
    let clearTime: NSTimeInterval = 60 // 60 * 60 * 24 * 7
    
    /// 清除数据库中的缓存数据
    func clearCacheStatus() {
        // 计算过期时间
        let clearDate = NSDate(timeIntervalSinceNow: -clearTime)
        
        // 转成数据库时间
        let df = NSDateFormatter()
        df.locale = NSLocale(localeIdentifier: "EN")
        df.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let time = df.stringFromDate(clearDate)
        print("clearDate: \(time)")
        
        // 删除数据库中的数据
        let sql = "DELETE FROM T_Status WHERE createTime < '\(time)';"
        
        SQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            do {
                try db.executeUpdate(sql, values: [])
                print("清除数据缓存成功了")
            } catch let error as NSError {
                print("SQL error: \(error)")
            }
        }
    }
    
    /*
        1. 先从本地数据库查找微博数据
        2. 本地有数据直接返回
        3. 本地没有数据,就发送网络请求去服务器加载数据
        4. 网络加载返回数据后,保存到本地,返回给调用的人
    */
    func dalLoadStatus(since_id: Int64, max_id: Int64, dalLoadStatusCallback: (error: NSError?, statuses: [[String: AnyObject]]?) -> Void) {
        // 1. 先从本地数据库查找微博数据
        loadLocalStatus(since_id, max_id: max_id) { (loadStatuses, loadError) -> Void in
            if loadError != nil {
                print("加载数据库数据出错了: \(loadError)")
                dalLoadStatusCallback(error: loadError, statuses: nil)
                return
            }
            
            // 没有出错
            if loadStatuses != nil && loadStatuses?.count > 0 {
                // 从本地数据库加载到了数据
                // 2. 本地有数据直接返回
                print("本地有数据 \(loadStatuses?.count)")
                dalLoadStatusCallback(error: nil, statuses: loadStatuses)
                return
            }
            
            // 3. 本地没有数据,就发送网络请求去服务器加载数据
            
            guard let access_token = HMUserAccountViewModel.sharedUserAccountViewModel.userAccount?.access_token else {
                // access_token 没有值
                print("access_token 没有值")
                return
            }
            
            // urlString
            let urlString = "2/statuses/home_timeline.json"
            
            var parameters: [String: AnyObject] = [
                "access_token": access_token,
            ]
            
            /// 如果传入了since_id
            if since_id > 0 {
                parameters["since_id"] = NSNumber(longLong: since_id)
            } else if max_id > 0 {
                parameters["max_id"] = NSNumber(longLong: max_id - 1)
            }
            
            HMNetworkTool.sharedNetworkTool.requestGET(urlString, parameters: parameters, progress: nil, success: { (_, responseObject) -> Void in
                // 解析返回数据
                let reslut = responseObject as? [String: AnyObject]
                // 获取字典中的 statuses 对应的微博字典数组
                if let statusesArray = reslut?["statuses"] as? [[String: AnyObject]] {
                    
                    // 4. 网络加载返回数据后,保存到本地
                    self.saveStatus(statusesArray)
                    
                    // 5. 返回给调用的人
                    dalLoadStatusCallback(error: nil, statuses: statusesArray)
                } else {
                    // 5. 返回给调用的人
                    dalLoadStatusCallback(error: nil, statuses: nil)
                }
                }, failure: { (_, error: NSError) -> Void in
                    dalLoadStatusCallback(error: loadError, statuses: nil)
            })
        }
    }
    
    /// 加载本地数据库中的微博数据
    private func loadLocalStatus(since_id: Int64, max_id: Int64, loadCallback: (statuses: [[String: AnyObject]]?, error: NSError?) -> Void) {
        let userId = HMUserAccountViewModel.sharedUserAccountViewModel.userAccount?.uid
        
        // 断言,方便调试,在开发阶段就可以解决问题
        assert(userId != nil, "uid 为 nil 了")
        
        var sql = "SELECT statusId, status, userId FROM T_Status \n" +
        "WHERE userId = \(userId!) \n"
        
        if since_id > 0 {
            // 要下拉刷新,加载比 since_id 大的微博
            sql += "AND statusId > \(since_id) \n"
        } else if max_id > 0 {
            // 上拉加载更多,加载比max_id小的微博
            sql += "AND statusId < \(max_id) \n"
        }
        
        sql += "ORDER BY statusId DESC LIMIT 20;"
        
        // 查询
        SQLiteManager.sharedManager.dbQueue.inDatabase { (db) -> Void in
            do {
                // 获取查询的结果集,所有数据都是通过这个结果集来获取
                let resultSet = try db.executeQuery(sql, values: [])
                
                // 微博字典数组
                var statusesArray = [[String: AnyObject]]()
                
                // 获取查询的数据
                while resultSet.next() {
                    // 有一条微博记录
                    // 获取这条微博记录中的字段信息
//                    let statusId = resultSet.intForColumn("statusId")
                    
                    // 一条微博字符串
                    let statusString = resultSet.stringForColumn("status")
                    
                    // 微博 String -> NSData -> 微博字典(json)
                    let data = statusString.dataUsingEncoding(NSUTF8StringEncoding)!
                    
                    let statusDcit = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions(rawValue: 0)) as! [String: AnyObject]
                    
                    statusesArray.append(statusDcit)
                }
                loadCallback(statuses: statusesArray, error: nil)

            } catch let error as NSError {
                print("SQL error: \(error)")
                loadCallback(statuses: nil, error: error)
            }
        }
    }
    
    /// 保存微博数据
    private func saveStatus(statuses: [[String: AnyObject]]) {
        let userId = HMUserAccountViewModel.sharedUserAccountViewModel.userAccount?.uid
        
        // 断言,方便调试,在开发阶段就可以解决问题
        assert(userId != nil, "uid 为 nil 了")
        
        let sql = "INSERT INTO T_Status (statusId, status, userId) VALUES (?, ?, \(userId!));"
        
        // 执行SQL
        SQLiteManager.sharedManager.dbQueue.inTransaction { (db, rollback) -> Void in
            // 遍历每条微博数据
            for dict in statuses {
                
                do {
                    let statusId = dict["id"] as! NSNumber
                    // 数据库不能直接存放字典
                    // 字典(json) -> NSData -> String
                    let data = try NSJSONSerialization.dataWithJSONObject(dict, options: NSJSONWritingOptions(rawValue: 0))
                    
                    let statusStr = String(data: data, encoding: NSUTF8StringEncoding)!
                    
                    try db.executeUpdate(sql, values: [statusId, statusStr])
                    
                } catch let error as NSError {
                    print("SQL error: \(error)")
                }
            }
            
            print("保存了 \(statuses.count) 条微博数据到数据库")
        }
    }
}
